/**
 *
 */
package idao.engine.parameter;

import idao.engine.DaoUtils;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.regex.Pattern;

/**
 * Represent a sql parameter in the specified sql statment.
 * 
 * @author huhao
 */
public abstract class SqlParameter
{
    // Regex used to determine parameter type
    private static final Pattern ARG_INDEX = Pattern.compile("^\\d$");
    private static final Pattern ARG_INDEX_THEN_OGNL = Pattern.compile("^\\d\\..+$");

    public static SqlParameter getParameter(int parameterIndex, String parameterExpression)
    {
        if (ARG_INDEX.matcher(parameterExpression).matches()) {
            return new ArgIndexParameter(parameterIndex, parameterExpression);
        }
        if (ARG_INDEX_THEN_OGNL.matcher(parameterExpression).matches()) {
            return new ArgIndexThenOgnlParameter(parameterIndex, parameterExpression);
        }
        return new OgnlParameter(parameterIndex, parameterExpression);
    }

    private int parameterIndex;
    private String prameterExpression;

    protected SqlParameter(int parameterIndex, String prameterExpression)
    {
        this.parameterIndex = parameterIndex;
        this.prameterExpression = prameterExpression;
    }

    public void setValue(PreparedStatement ps, Object[] args) throws SQLException
    {
        Object value = this.getParameterValue(args);
        this.setParameterValue(ps, value);
    }

    protected abstract Object getParameterValue(Object[] args);

    protected void setParameterValue(PreparedStatement ps, Object value) throws SQLException
    {
        DaoUtils.setValue(ps, parameterIndex, value);
    }

    public int getParameterIndex()
    {
        return parameterIndex;
    }

    public String getPrameterExpression()
    {
        return prameterExpression;
    }
}
